import errorCode from '@/utils/request/errorCode'
import {
  refreshToken
} from '@/api/auth'
import {
  getStore
} from '@/utils/store.js'

// 请求队列
let requestList = []
// 是否正在刷新中
let isRefreshToken = false
let isAutoLogin = false
const scope = 'server'

/**
 * 响应拦截
 * @param {Object} http
 */
module.exports = vm => {
  uni.$u.http.interceptors.response.use(async res => {
    const status = Number(res.statusCode) || 200
    const code = res.data.code || 0
    const message = res.data.msg || errorCode[status] || errorCode['default']
    if (code === 1) {
      uni.$u.toast(message)
      return Promise.reject(message)
    }
    return res.data
  }, async err => {
    const status = Number(err.statusCode) || 500

    if ((status === 401 && !vm.$store.getters.refreshToken) || status === 424) {
      // 1. 如果获取不到刷新令牌，则进行自动登陆
      if (!isAutoLogin) {
        isAutoLogin = true
        vm.$store.commit('CLEAR_LOGIN_INFO')
        // #ifdef MP-WEIXIN
        uni.login({
          provider: 'weixin',
          success: res => {
            vm.$store.dispatch('Login', {
              type: 2,
              data: {
                state: 'MINI',
                loginCode: res.code
              }
            }).then(res => {
              console.log('令牌过期自动登陆成功', res)
              // requestList.forEach(cb => cb())
              // return uni.$u.http.request(err.config) //如果请求一直无法请求成功，会形成递归
              return Promise.reject()
            })
          }
        })
        // #endif
      }
    } else if (status === 401) {
      // 如果未认证，并且未进行刷新令牌，说明可能是访问令牌过期了
      if (!isRefreshToken) {
        isRefreshToken = true
        // 2. 进行刷新访问令牌
        try {
          const grant_type = 'refresh_token'
          const basicAuth = getStore({
            name: 'basicAuth'
          })
          const refreshTokenRes = await refreshToken({
            refresh_token: uni.getStorageSync('REFRESH_TOKEN'),
            scope: scope,
            grant_type: grant_type
          }, {
            isToken: false,
            'content-type': 'application/x-www-form-urlencoded',
            'Authorization': basicAuth
          })
          console.log('令牌过期刷新token：', refreshTokenRes)
          // 2.1 刷新成功，则回放队列的请求 + 当前请求
          vm.$store.commit('SET_TOKEN', refreshTokenRes.data)
          requestList.forEach(cb => cb())
          return uni.$u.http.request(err.config)
        } catch (e) {
          // 为什么需要 catch 异常呢？刷新失败时，请求因为 Promise.reject 触发异常。
          // 2.2 刷新失败，只回放队列的请求
          requestList.forEach(cb => cb())
          // 登出。即不回放当前请求！不然会形成递归
          vm.$store.commit('CLEAR_LOGIN_INFO')
          // return Promise.reject(err.data)
          return Promise.reject(message)
        } finally {
          requestList = []
          isRefreshToken = false
        }
      } else {
        // 添加到队列，等待刷新获取到新的令牌
        return new Promise(resolve => {
          return Promise.reject(message)
          // requestList.push(() => {
          // 	err.config.header.Authorization = 'Bearer ' + vm.$store
          // 		.getters.accessToken // 让每个请求携带自定义token 请根据实际情况自行修改
          // 	resolve(uni.$u.http.request(err.config))
          // })
        })
      }
    }

    try {
      var message = err.data.msg
    } catch (error) {
      message = undefined
    }
    message = message || errorCode[status] || errorCode['default']
    if (!message) {
      message = '系统发生未知错误'
    } else if (message === 'Network Error') {
      message = '后端接口连接异常'
    } else if (message.includes('timeout')) {
      message = '系统接口请求超时'
    } else if (message.includes('Request failed with status code')) {
      message = '系统接口' + message.substring(message.length - 3) + '异常'
    }
    uni.$u.toast(message)
    console.error(message)
    return Promise.reject(new Error(message, status))
  })
}
